// Fill out your copyright notice in the Description page of Project Settings.


#include "Algorithm/Octree/Octree.h"
#include "Kismet/KismetMathLibrary.h"

AOctree::AOctree()
{
	PrimaryActorTick.bCanEverTick = true;
}

void AOctree::BeginPlay()
{
	Super::BeginPlay();
	OctreeNode::worldObject = GetWorld();
	root = MakeShareable(new OctreeNode(FVector(0, 0, 400), FVector(400, 400, 400), 0));
	GetWorld()->GetTimerManager().SetTimer(timer, this, &AOctree::SpawnActors, playRate, true);
	GetWorld()->GetTimerManager().SetTimer(timer2, this, &AOctree::ActorsAddVelocity, 2, true);
}

void AOctree::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (root.IsValid())
	{
		// 更新状态
		root->UpdateState();
		if (traceActor)
		{
			// 判断是否在扫描器的范围内
			root->TraceObjectInRange(traceActor, affectRadianRange);
		}
	}
}

void AOctree::SpawnActors()
{
	if (cubeCount < 0)
	{
		GetWorld()->GetTimerManager().ClearTimer(timer);
		return;
	}
	cubeCount--;
	FVector pos = FVector(UKismetMathLibrary::RandomIntegerInRange(-widthX / 2 + 10, widthX / 2 - 10),
	                      UKismetMathLibrary::RandomIntegerInRange(-widthY / 2 + 10, widthY / 2 - 10),
	                      UKismetMathLibrary::RandomIntegerInRange(10, widthZ - 10));
	FTransform trans = FTransform(FRotator(0, UKismetMathLibrary::RandomFloatInRange(0, 360), 0), pos, FVector(0.2));
	ABattery* actor = GetWorld()->SpawnActor<ABattery>(BatteryClass, trans);
	if (IsValid(actor))
	{
		objs.Add(actor);
		root->InsertObject(actor);
	}
}

void AOctree::ActorsAddVelocity()
{
	for (ABattery* actor : objs)
	{
		actor->GetStaticMeshComponent()->SetPhysicsLinearVelocity(UKismetMathLibrary::RandomUnitVector() * 100);
		if (traceActor)
		{
			Cast<ABattery>(traceActor)->GetStaticMeshComponent()->SetPhysicsLinearVelocity(
				UKismetMathLibrary::RandomUnitVector() * 250);
		}
	}
}
